﻿
//元件定义信息分析类
namespace n_Vdata
{
using System;
using n_ConstString;
using n_ET;
using n_MemberType;
using n_Parse;
using n_ParseNet;
using n_VdataList;
using n_VdataNode;
using n_WordList;
using n_VarType;

public static class Vdata
{
	static string UnitName;
	
	//获取元件信息,生成: 元件列表 函数列表 变量列表
	public static void Record()
	{
		//虚拟数据类型列表初始化
		VdataList.Clear();
		
		Parse.DealWith( ref UnitName, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 成员列表( int Index )
	{
		for( int i = 1; i < ParseNet.NodeSet[ Index ].Length; ++i ) {
			int index = int.Parse( ParseNet.NodeSet[ Index ][ i ] );
			
			//判断是否元件定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.元件 ) {
				元件( index );
				continue;
			}
			//判断是否虚拟数据定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.虚拟数据定义 ) {
				虚拟数据定义( index );
				continue;
			}
		}
	}
	
	static void 元件( int Index )
	{
		Parse.Unit( ref UnitName, Index, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 虚拟数据定义( int Index )
	{
		//获取成员类型
		string VisitType = null;
		string RealRefType = null;
		int MemberTypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		Parse.GetMemberType( MemberTypeIndex, ref VisitType, ref RealRefType );
		
		int VdataNameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
		string VdataName = UnitName + "." + WordList.GetWord( VdataNameIndex );
		
		//判断虚拟类型名是否存在
		if( VdataList.isExist( VdataName ) ) {
			ET.WriteParseError( VdataNameIndex,	"已经定义了同名的虚拟数据类型: " + VdataName );
		}
		string sDataType = null;
		string sAddrType = null;
		string sUnitType = null;
		string sPreName = null;
		int Start = 0;
		int End = 0;
		bool AutoAllot = false;
		
		int MemberIndex = int.Parse( ParseNet.NodeSet[ Index ][ 5 ] );
		int Length = ParseNet.NodeSet[ MemberIndex ].Length;
		for( int i = 1; i < Length; ++i ) {
			int MemIndex = int.Parse( ParseNet.NodeSet[ MemberIndex ][ i ] );
			
			//判断是否为虚拟数据元件引用
			if( ParseNet.NodeSet[ MemIndex ][ 0 ] == ParseNet.Node.虚拟数据元件引用 ) {
				if( sUnitType != null ) {
					int UnitErrorIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 1 ] );
					ET.WriteParseError( UnitErrorIndex, "虚拟数据类型定义中已定义元件链接目标" );
				}
				int UnitLinkIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 3 ] );
				int eIndex = -1;
				string Name = null;
				Parse.GetMemberNames( UnitName, UnitLinkIndex, ref Name, ref eIndex );
				sUnitType = Name;
			}
			else if( ParseNet.NodeSet[ MemIndex ][ 0 ] == ParseNet.Node.虚拟数据前缀指定 ) {
				if( sPreName != null ) {
					int UnitErrorIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 1 ] );
					ET.WriteParseError( UnitErrorIndex, "虚拟数据类型定义中已定义前缀指定" );
				}
				int VdataPreNameIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 3 ] );
				sPreName = WordList.GetWord( VdataPreNameIndex );
			}
			//判断是否为虚拟数据地址限定
			else {
				if( sAddrType != null ) {
					int UnitErrorIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 1 ] );
					ET.WriteParseError( UnitErrorIndex, "虚拟数据类型定义中已定义地址类型" );
				}
				//解析数据类型
				int DataTypeIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 7 ] );
				sDataType = WordList.GetWord( DataTypeIndex );
				if( sDataType != VarType.BaseType.Bit && !VarType.BaseType.isUint( sDataType ) ) {
					ET.WriteParseError( DataTypeIndex,
					                   "虚拟数据类型中的数据类型应为无符号数类型: " + sDataType );
				}
				//获取地址类型 判断是否自动分配
				int AddrTypeIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 4 ] );
				sAddrType = WordList.GetWord( AddrTypeIndex );
				if( !VarType.BaseType.isUint( sAddrType ) ) {
					ET.WriteParseError( Index, "虚拟数据类型中的地址类型应为无符号类型: " + sAddrType );
				}
				//读取地址类型和地址区间
				int AreaIndex = int.Parse( ParseNet.NodeSet[ MemIndex ][ 5 ] );
				if( AreaIndex == -1 ) {
					AutoAllot = false;
					continue;
				}
				AutoAllot = true;
				
				//获取地址区间
				int StartIndex = int.Parse( ParseNet.NodeSet[ AreaIndex ][ 1 ] );
				int EndIndex = int.Parse( ParseNet.NodeSet[ AreaIndex ][ 3 ] );
				
				//string SStart = WordList.GetWord( StartIndex );
				//string SEnd = WordList.GetWord( EndIndex );
				string SStart = ConstExpression.GetExpressionValue( StartIndex, UnitName );
				string SEnd = ConstExpression.GetExpressionValue( EndIndex, UnitName );
				
				string StartType = null;
				string EndType = null;
				SStart = ConstString.GetValue( ref StartType, SStart, StartIndex );
				SEnd = ConstString.GetValue( ref EndType, SEnd, EndIndex );
				Start = int.Parse( SStart );
				End = int.Parse( SEnd );
				
				if( Start > End ) {
					ET.WriteParseError( StartIndex, "虚拟数据类型中的起始地址不能大于结束地址: " + Start + " - " + End );
				}
				if( sAddrType == VarType.BaseType.Uint8 ) {
					if( End > 0xFF ) {
						ET.WriteParseError( EndIndex, "虚拟数据类型中的地址常量超出地址数据类型: " + sAddrType + " - " + End );
					}
				}
				if( sAddrType == VarType.BaseType.Uint16 ) {
					if( End > 0xFFFF ) {
						ET.WriteParseError( EndIndex, "虚拟数据类型中的地址常量超出地址数据类型: " + sAddrType + " - " + End );
					}
				}
			}
		}
		if( sDataType == null ) {
			sDataType = VarType.BaseType.Bit;
		}
		if( sUnitType == null ) {
			sUnitType = UnitName;
		}
		VdataNode node = new VdataNode(
			VisitType, RealRefType, VdataName, sDataType, sAddrType, sUnitType, AutoAllot, Start, End, UnitName, sPreName );
		VdataList.Add( node );
		
		//处理链接类型
		int LinkIndex = int.Parse( ParseNet.NodeSet[ Index ][ 7 ] );
		if( LinkIndex != -1 ) {
			//提取第二个成员信息
			int SecondIndex = int.Parse( ParseNet.NodeSet[ LinkIndex ][ 2 ] );
			int ErrorIndex2 = 0;
			string SecondName = null;
			Parse.GetMemberNames( UnitName, SecondIndex, ref SecondName, ref ErrorIndex2 );
			if( RealRefType != MemberType.RealRefType.link ) {
				ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 4 ] ), "连接器的左端必须为引用类型成员:" + UnitName );
			}
			node.TargetMemberName = SecondName;
		}
	}
}
}

